#include "stdio.h"
#include "stdlib.h"
#include "conio.h"

int n = 0, time = 0;
float eti = 0.0, ewi = 0.0;

struct jcb {
    char name[10]; 
    char state; 
    int ts; 
    int tb; 
    int tc; 
    float ti; 
    int priority; 
    struct jcb *link; 
};

typedef struct jcb JCB;

JCB *head = NULL, *q = NULL;

JCB* getjcb() {
    return (JCB*)malloc(sizeof(JCB));
}

void initial();
void print(JCB *pr);
void last();
void sjf();
void fcfs();
void running(JCB *p);
void runjcb(int m);
void start();

void initial() {
    int i;
    printf("\nInput jcb num\n");
    scanf("%d", &n);
    printf("Input\nname\tts\tntime\tpriority\n");
    for (i = 0; i < n; i++) {
        JCB *p = getjcb();
        scanf("%s\t%d\t%d\t%d", p->name, &p->ts, &p->ntime, &p->priority);
        p->state = 'W';
        p->link = NULL;
        if (head == NULL) head = q = p;
        else {
            q->link = p;
            q = p;
        }
    }
}

void print(JCB *pr) {
    JCB *p;
    printf("\ntime=%d", time);
    printf("\nname\tstate\tts\tntime\tpriority\ttb\ttc\tti\twi\n");
    printf("%s\t%c\t%d\t%d\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
           pr->name, pr->state, pr->ts, pr->ntime, pr->priority, pr->tb, pr->tc, pr->ti, pr->wi);
    p = head;
    do {
        if (p->state == 'W')
            printf("%s\t%c\t%d\t%d\t%d\n",
                   p->name, p->state, p->ts, p->ntime, p->priority);
        p = p->link;
    } while (p != NULL);
    p = head;
    do {
        if (p->state == 'F')
            printf("%s\t%c\t%d\t%d\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
                   p->name, p->state, p->ts, p->ntime, p->priority, p->tb, p->tc, p->ti, p->wi);
        p = p->link;
    } while (p != NULL);
}

void last() {
    eti /= n;
    ewi /= n;
    printf("\neti=%7.3f\tewi=%7.3f\n", eti, ewi);
}

void sjf() {
    JCB *min;
    int i, iden;
    for (i = 0; i < n; i++) {
        JCB *p = head;
        min = head;
        iden = 1;
        do {
            if (p->state == 'W' && p->ts <= time)
                if (iden) {
                    min = p;
                    iden = 0;
                } else if (p->ntime < min->ntime) min = p;
            p = p->link;
        } while (p != NULL);
        if (iden) {
            i--;
            printf("\ntime=%d:\tno JCB submitted...wait...", time);
            time++;
            if (time > 100) {
                printf("\nruntime is too long...error");
                getch();
            }
        } else {
            running(min);
        }
    }
}

void fcfs() {
    JCB *min;
    int i, iden;
    for (i = 0; i < n; i++) {
        JCB *p = head;
        min = head;
        iden = 1;
        do {
            if (p->state == 'W' && p->ts <= time)
                if (iden) {
                    min = p;
                    iden = 0;
                } else if (p->ts < min->ts) min = p;
            p = p->link;
        } while (p != NULL);

        if (iden) {
            i--;
            printf("\ntime=%d:\tno JCB submitted...wait...", time);
            time++;
            if (time > 100) {
                printf("\nruntime is too long...error");
                getch();
            }
        } else {
            running(min);
        }
    }
}

void running(JCB *p) {
    p->tb = time;
    p->state = 'R';
    p->tc = p->tb + p->ntime;
    p->ti = (float)(p->tc - p->ts);
    p->wi = (float)(p->ti / p->ntime);
    eti += p->ti;
    ewi += p->wi;
    print(p);
    time += p->ntime;
    p->state = 'F';
    printf("\n%s has been finished!\npress any key to continue...\n", p->name);
    getch();
}

void runjcb(int m) {
    printf("\n\nstart running jcb using algorithm %d.", m);
    switch (m) {
        case 1:
            fcfs();
            break;
        case 2:
            sjf();
            break;
        default:
            printf("\nrunjcb error...\n");
            exit(0);
    }
}

void start() {
    int m;
    char str[100] = "\nselect algorithm\n1.FCFS\n2.SJF\n";
    printf("%s", str);
    m = getch() - '0';
    initial();
    if (1 <= m && m <= 2) runjcb(m);
    else {
        printf("\nselect error! try again...\n");
        start();
    }
    last();
}

int main() {
    start();
    printf("\nfinished!");
    getch();
    return 0;
}

